package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        int THRESHOLD = 99;
        if (boundHashOperations.hasKey(skuId.toString())) {
            // 添加
            CartInfo cartInfo = boundHashOperations.get(skuId.toString());
            int totalNum = cartInfo.getSkuNum() + skuNum;

            cartInfo.setSkuNum(totalNum>THRESHOLD? THRESHOLD:totalNum);
            boundHashOperations.put(skuId.toString(),cartInfo);
        }else {
            // 新增
            Long size = boundHashOperations.size();
            if (size>=50) {
                throw new ServiceException("购物车数量不能超过50");
            }

            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            R<ProductSku> remoteProductSkuR =
                    remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (remoteProductSkuR.getCode() == R.FAIL) {
                throw new ServiceException(remoteProductSkuR.getMsg());
            }
            ProductSku remoteProductSku = remoteProductSkuR.getData();

            cartInfo.setCartPrice(remoteProductSku.getSalePrice());
            cartInfo.setSkuName(remoteProductSku.getSkuName());
            cartInfo.setThumbImg(remoteProductSku.getThumbImg());
            cartInfo.setSkuPrice(remoteProductSku.getSalePrice());
            cartInfo.setSkuNum(skuNum>THRESHOLD? THRESHOLD:skuNum);

            boundHashOperations.put(skuId.toString(),cartInfo);
        }

    }

    /**
     * 查询购物车
     *
     * @return
     */
    @Override
    public List<CartInfo> getCartList() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        if (boundHashOperations.size()>0) {
            List<CartInfo> values = boundHashOperations.values();
            List<Long> skuIdlist = values.stream().map(CartInfo::getSkuId).toList();

            R<List<SkuPrice>> skuPriceList = remoteProductService.getSkuPriceList(skuIdlist, SecurityConstants.INNER);
            Map<Long, BigDecimal> skuIdToSalePrice = skuPriceList.getData().stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            for (CartInfo value : values) {
                value.setSkuPrice(skuIdToSalePrice.get(value.getSkuId()));
            }
            return values;
        }
        return new ArrayList<>();
    }

    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        boundHashOperations.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        if (boundHashOperations.hasKey(skuId.toString())) {
            CartInfo cartInfo = boundHashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            boundHashOperations.put(skuId.toString(),cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();
        values.forEach(item->{
            item.setIsChecked(isChecked);
            boundHashOperations.put(item.getSkuId().toString(),item);
        });
    }

    /**
     * 清空购物车
     */
    @Override
    public void clearCart() {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        redisTemplate.delete(cartKey);
    }

    /**
     * 查询用户购物车列表中选中商品列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();

        String cartKey = getCartKey(userId);
        List<CartInfo> cartCachInfoList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(cartCachInfoList)) {
            for (CartInfo cartInfo : cartCachInfoList) {
                if (cartInfo.getIsChecked() == 1) {
                    cartInfoList.add(cartInfo);
                }
            }
        }
        return cartInfoList;
    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = getCartKey(userId);

        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartCacheList = boundHashOperations.values();

        if (!CollectionUtils.isEmpty(cartCacheList)) {
            List<Long> skuIdList = cartCacheList.stream().map(CartInfo::getSkuId).toList();
            // 获取最新价格
            R<List<SkuPrice>> skuPriceListR = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            if (R.FAIL == skuPriceListR.getCode()) {
                throw new ServiceException(skuPriceListR.getMsg());
            }
            List<SkuPrice> skuPriceList = skuPriceListR.getData();
            Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream()
                    .collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            // 赋值最新价格
            for (CartInfo cartInfo : cartCacheList) {
                cartInfo.setSkuPrice(skuIdToSalePriceMap.get(cartInfo.getSkuId()));
                boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
            }
        }
        return true;
    }

    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartKey = getCartKey(userId);

        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();
        for (CartInfo value : values) {
            if (value.getIsChecked() == 1) {
                boundHashOperations.delete(value.getSkuId().toString());
            }
        }
        return true;
    }

    private String getCartKey(Long userId) {
        String cartKey = "user:cart" + userId;
        return cartKey;
    }




}